package org.apache.qpid.management.common.sasl;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import org.apache.harmony.javax.security.auth.callback.Callback;
import org.apache.harmony.javax.security.auth.callback.CallbackHandler;
import org.apache.harmony.javax.security.auth.callback.NameCallback;
import org.apache.harmony.javax.security.auth.callback.PasswordCallback;
import org.apache.harmony.javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.harmony.javax.security.sasl.SaslClient;
import org.apache.harmony.javax.security.sasl.SaslException;

public class PlainSaslClient
  implements SaslClient
{
  private static byte SEPARATOR = 0;
  private String authenticationID;
  private String authorizationID;
  private CallbackHandler cbh;
  private boolean completed = false;
  private byte[] password;

  public PlainSaslClient(String paramString, CallbackHandler paramCallbackHandler)
    throws SaslException
  {
    this.cbh = paramCallbackHandler;
    Object[] arrayOfObject = getUserInfo();
    this.authorizationID = paramString;
    this.authenticationID = ((String)arrayOfObject[0]);
    this.password = ((byte[])arrayOfObject[1]);
    if ((this.authenticationID == null) || (this.password == null))
      throw new SaslException("PLAIN: authenticationID and password must be specified");
  }

  private void clearPassword()
  {
    int i;
    if (this.password != null)
      i = 0;
    while (true)
    {
      if (i >= this.password.length)
      {
        this.password = null;
        return;
      }
      this.password[i] = 0;
      ++i;
    }
  }

  private Object[] getUserInfo()
    throws SaslException
  {
    NameCallback localNameCallback;
    try
    {
      localNameCallback = new NameCallback("PLAIN authentication id: ");
      PasswordCallback localPasswordCallback = new PasswordCallback("PLAIN password: ", false);
      CallbackHandler localCallbackHandler = this.cbh;
      Callback[] arrayOfCallback = new Callback[2];
      arrayOfCallback[0] = localNameCallback;
      arrayOfCallback[1] = localPasswordCallback;
      localCallbackHandler.handle(arrayOfCallback);
      String str = localNameCallback.getName();
      char[] arrayOfChar = localPasswordCallback.getPassword();
      if (arrayOfChar != null)
      {
        arrayOfByte = new String(arrayOfChar).getBytes("UTF8");
        localPasswordCallback.clearPassword();
        Object[] arrayOfObject = new Object[2];
        arrayOfObject[0] = str;
        arrayOfObject[1] = arrayOfByte;
        return arrayOfObject;
      }
      byte[] arrayOfByte = (byte[])null;
    }
    catch (IOException localIOException)
    {
      throw new SaslException("Cannot get password", localIOException);
    }
    catch (UnsupportedCallbackException localUnsupportedCallbackException)
    {
      throw new SaslException("Cannot get userid/password", localUnsupportedCallbackException);
    }
  }

  public void dispose()
    throws SaslException
  {
    clearPassword();
  }

  public byte[] evaluateChallenge(byte[] paramArrayOfByte)
    throws SaslException
  {
    if (this.completed)
      throw new IllegalStateException("PLAIN: authentication already completed");
    this.completed = true;
    while (true)
    {
      try
      {
        Object localObject;
        if (this.authorizationID == null)
          localObject = null;
        while (true)
        {
          byte[] arrayOfByte2 = this.authenticationID.getBytes("UTF8");
          int i = 2 + this.password.length + arrayOfByte2.length;
          if (localObject == null)
            break;
          j = localObject.length;
          byte[] arrayOfByte3 = new byte[i + j];
          if (localObject == null)
            break label204;
          System.arraycopy(localObject, 0, arrayOfByte3, 0, localObject.length);
          k = localObject.length;
          int l = k + 1;
          arrayOfByte3[k] = SEPARATOR;
          System.arraycopy(arrayOfByte2, 0, arrayOfByte3, l, arrayOfByte2.length);
          int i1 = l + arrayOfByte2.length;
          int i2 = i1 + 1;
          arrayOfByte3[i1] = SEPARATOR;
          System.arraycopy(this.password, 0, arrayOfByte3, i2, this.password.length);
          clearPassword();
          return arrayOfByte3;
          byte[] arrayOfByte1 = this.authorizationID.getBytes("UTF8");
          localObject = arrayOfByte1;
        }
        int j = 0;
      }
      catch (UnsupportedEncodingException localUnsupportedEncodingException)
      {
        throw new SaslException("PLAIN: Cannot get UTF-8 encoding of ids", localUnsupportedEncodingException);
      }
      label204: int k = 0;
    }
  }

  protected void finalize()
  {
    clearPassword();
  }

  public String getMechanismName()
  {
    return "PLAIN";
  }

  public Object getNegotiatedProperty(String paramString)
  {
    if (this.completed)
    {
      String str;
      if (paramString.equals("javax.security.sasl.qop"))
        str = "auth";
      while (true)
      {
        return str;
        str = null;
      }
    }
    throw new IllegalStateException("PLAIN: authentication not completed");
  }

  public boolean hasInitialResponse()
  {
    return true;
  }

  public boolean isComplete()
  {
    return this.completed;
  }

  public byte[] unwrap(byte[] paramArrayOfByte, int paramInt1, int paramInt2)
    throws SaslException
  {
    if (this.completed)
      throw new IllegalStateException("PLAIN: this mechanism supports neither integrity nor privacy");
    throw new IllegalStateException("PLAIN: authentication not completed");
  }

  public byte[] wrap(byte[] paramArrayOfByte, int paramInt1, int paramInt2)
    throws SaslException
  {
    if (this.completed)
      throw new IllegalStateException("PLAIN: this mechanism supports neither integrity nor privacy");
    throw new IllegalStateException("PLAIN: authentication not completed");
  }
}